package com.honry.identityaccess.domain.model.identity;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.hibernate.annotations.Proxy;

import com.honry.common.domain.model.ConcurrencySafeEntity;
import com.honry.common.domain.model.DomainEventPublisher;
import com.honry.identityaccess.domain.model.DomainRegistry;


public class User extends ConcurrencySafeEntity{
	private static final long serialVersionUID = 1L;
	
	private String username;//用户名,为实体标识信息.
	
	private String password;//用户密码.
	
	private Person person;
	public Person person(){
		return this.person;
	}
	protected void setPerson(Person person) {
        this.assertArgumentNotNull(person, "The person is required.");

        this.person = person;
    }
	public User() {
		super();
	}
	public User(String username,String password,Person person) {
		this.setUsername(username);
		this.protectPassword("", password);
		this.setPerson(person);
		person.internalOnlySetUser(this);
	}
	
	
	public String username()
	{
		return this.username;
	}
	
	public void setUsername(String username){
		this.username=username;
	}
	
	public String password(){
		return this.password;
	}
	private void setPassword(String password){
		this.password=password;
	}
	
	/**
	 * 将提供明文加密后返回。
	 * @param plainTextPassword
	 * @return
	 */
	protected String asEncryptedValue(String plainTextPassword) {
        String encryptedValue =
            DomainRegistry
                .encryptionService()
                .encryptedValue(plainTextPassword);

        return encryptedValue;
    }
	/**
	 * 判断当前密码和要修改的密码不能相同。
	 * @param currentPassword 	当前密码
	 * @param changedPassword	新密码
	 */
	protected void assertPasswordsNotSame(String oldPassword, String newPassword) {
        this.assertArgumentNotEquals(
        		oldPassword,
        		newPassword,
                "密码没有修改.");
    }

    /**
     * 密码安全级别检测
     * @param plainTextPassword 密码明文
     */
    protected void assertPasswordNotWeak(String plainTextPassword) {
        /*this.assertArgumentFalse(
                DomainRegistry.passwordService().isWeak(plainTextPassword),
                "The password must be stronger.");*/
    }

    /**
     * 检测用户名和密码是否一样
     * @param plainTextPassword
     */
    protected void assertUsernamePasswordNotSame(String plainTextPassword) {
        this.assertArgumentNotEquals(
                this.username(),
                plainTextPassword,
                "用户名和密码不能相同.");
    }
	/**
	 * 密码更改事件
	 * @param oldPassword
	 * @param newPassword
	 */
	public void changePassword(String oldPassword,String newPassword){
		this.assertArgumentNotEmpty(
				oldPassword,
                "必须提供当前和新密码.");

        this.assertArgumentEquals(
                this.password(),
                this.asEncryptedValue(oldPassword),
                "提供地旧密码不正确."); 
		this.protectPassword(oldPassword, newPassword);
		 //发布密码更改事件
		 DomainEventPublisher.instance().publish(new UserPasswordChanged(this.username));
	}
	protected void protectPassword(String oldPassword, String newPassword) {
        this.assertPasswordsNotSame(oldPassword, newPassword);

        this.assertPasswordNotWeak(newPassword);

        this.assertUsernamePasswordNotSame(newPassword);

        this.setPassword(this.asEncryptedValue(newPassword));
    }
	@Override
	public boolean equals(Object object){
		boolean equalsObjects=false;
		if(object!=null&&object.getClass()==this.getClass()){
			User typeObject=(User)object;
			equalsObjects=this.username.equals(typeObject.username);
		}
		return equalsObjects;
	}
	@Override
	public int hashCode()
	{
		int hashCodeValue=(45217 * 269)+this.username.hashCode();
		return hashCodeValue;
	}
	@Override
	public String toString()
	{
		return "User [ username=" + this.username + "]";
	}
}
